package com.example.springstudy.utils;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import com.example.springstudy.entity.SysUserDetails;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class JwtUtil {
    public static String keyStr = "123456012345012340123012010";
    public static int ttl = 7200;
    public static String createToken(Authentication authentication){
        SysUserDetails userDetails = (SysUserDetails) authentication.getPrincipal();

        Map<String, Object> payload = new HashMap<>();
        payload.put("userId", userDetails.getUserId()); // 用户ID
        payload.put("deptId", userDetails.getDeptId()); // 部门ID
        payload.put("dataScope", userDetails.getDataScope()); // 数据权限范围

//         claims 中添加角色信息
        Set<String> roles = userDetails.getAuthorities().stream()
                .map(GrantedAuthority::getAuthority)
                .collect(Collectors.toSet());
        payload.put("authorities", roles);

        payload.put("promise", userDetails.getPerms());

        Date now = new Date();
        Date expiration = DateUtil.offsetSecond(now, ttl);
        payload.put(JWTPayload.ISSUED_AT, now);
        payload.put(JWTPayload.EXPIRES_AT, expiration);
        payload.put(JWTPayload.SUBJECT, userDetails.getUsername());
        payload.put(JWTPayload.JWT_ID, IdUtil.simpleUUID());

        byte[] key = keyStr.getBytes(StandardCharsets.UTF_8);
        return JWTUtil.createToken(payload, key);
    }

    /**
     * 从 JWT Token 中解析 Authentication  用户认证信息
     *
     * @param payloads JWT 载体
     * @return 用户认证信息
     */
    public static UsernamePasswordAuthenticationToken getAuthentication(JSONObject payloads) {
        SysUserDetails userDetails = new SysUserDetails();
        userDetails.setUserId(payloads.getLong("userId")); // 用户ID
        userDetails.setDeptId(payloads.getInt("deptId"));
        userDetails.setDataScope(payloads.getInt("dataScope")); // 数据权限范围

        userDetails.setUsername(payloads.getStr(JWTPayload.SUBJECT)); // 用户名
        // 角色集合
        Set<SimpleGrantedAuthority> authorities = payloads.getJSONArray("authorities")
                .stream()
                .map(authority -> new SimpleGrantedAuthority(Convert.toStr(authority)))
                .collect(Collectors.toSet());
        userDetails.setAuthorities(authorities);
        userDetails.setPerms(payloads.getJSONArray("promise").stream().map(i->(String)i).collect(Collectors.toSet()));
        return new UsernamePasswordAuthenticationToken(userDetails, "", authorities);
    }
}
